package com.seeyon.apps.cxgd.kit;

import com.seeyon.ctp.common.exceptions.BusinessException;
import com.seeyon.ctp.util.JDBCAgent;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * <pre>
 * 直接操作数据库的类
 * </pre>
 */
public class DBKit {

    /**
     * 执行SQL语句并返回结果集。
     *
     * @param sql 需要执行的SQL语句。
     * @param params SQL语句中的参数，如果SQL不需要参数，则可以传入null。
     * @return 执行SQL后返回的结果集列表，如果SQL是更新操作，则返回空列表。
     * @throws Exception 如果执行SQL过程中发生任何异常，则抛出此异常。
     */
    public static List<Map<String, Object>> excuteSQL(String sql, List<Object> params) throws Exception {
        // 初始化结果集列表
        List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
        // 创建JDBCAgent实例，用于执行SQL操作
        JDBCAgent jdbc = new JDBCAgent(true);
        try {
            // 根据params是否为空，决定是否传入参数执行SQL
            if (params == null) {
                jdbc.execute(sql);
            } else {
                jdbc.execute(sql, params);
            }
            // 如果SQL不以"update"开头（即不是更新操作），则将结果集转换为列表形式
            if (!sql.startsWith("update")) {
                list = jdbc.resultSetToList();
            }
        } catch (Exception e) {
            // 捕获并打印异常，然后重新抛出，以便调用者可以处理
            e.printStackTrace();
            throw e;
        } finally {
            // 无论执行是否成功，都关闭JDBCAgent连接
            jdbc.close();
        }
        // 返回结果集列表
        return list;
    }

    
    /**
     * 根据提供的SQL语句更新或删除数据。
     *
     * 本方法通过创建JDBCAgent实例来执行SQL语句，该语句可能是更新（UPDATE）或删除（DELETE）操作。
     * 方法返回执行SQL语句影响的行数。
     *
     * @param sql 要执行的SQL语句，必须是更新或删除操作的语句。
     * @return 执行SQL语句后影响的行数。
     * @throws BusinessException 如果执行SQL语句过程中出现业务异常，则抛出此异常。
     */
    public static int updateOrDelData(String sql) throws BusinessException {
        // 创建JDBCAgent实例，用于执行SQL语句。
        JDBCAgent jdbc = new JDBCAgent(true);
        int num = 0; // 用于存储执行SQL语句后影响的行数。

        try {
            // 执行传入的SQL语句。
            num = jdbc.execute(sql);
        } catch (SQLException e) {
            // 如果执行SQL语句过程中出现SQLException，则打印异常堆栈跟踪。
            e.printStackTrace();
        } finally {
            // 无论是否发生异常，都关闭JDBCAgent连接。
            jdbc.close();
        }

        // 返回执行SQL语句影响的行数。
        return num;
    }
    
    /**
     * 执行批量更新操作。
     * 通过传入SQL语句，使用JDBCAgent进行批量更新的准备和执行。
     * 如果在执行过程中遇到异常，将抛出BusinessException。
     *
     * @param sql 批量更新所使用的SQL语句。
     * @return 执行批量更新操作后的影响行数。
     * @throws BusinessException 如果在执行批量更新过程中遇到任何异常。
     */
    public static int updateBatch(String sql) throws BusinessException {
        // 创建JDBCAgent实例，用于后续的数据库操作。
        JDBCAgent agent = new JDBCAgent(true);
        try {
            // 准备批量更新操作，此处使用了批处理的prepare方法。
            agent.batch1Prepare(sql);
            // 执行批量更新操作，并返回执行结果。
            return agent.batch3Execute();
        } catch(Exception e) {
            // 如果在执行过程中遇到异常，抛出业务异常，并将捕获的异常作为原因。
            throw new BusinessException(e);
        } finally {
            // 无论操作成功还是失败，都关闭JDBCAgent实例，释放资源。
            agent.close();
        }
    }

    /**
     * 根据提供的SQL语句创建数据库表。
     *
     * 本方法通过JDBCAgent执行SQL语句来创建数据库表。它首先实例化一个JDBCAgent对象，
     * 然后尝试执行传入的SQL语句。如果执行成功，它将返回受影响的行数；
     * 如果执行过程中出现SQLException，错误将被打印到标准错误流中。
     *
     * @param sql 要执行的SQL语句，用于创建数据库表。
     * @return 执行SQL语句后受影响的行数。
     * @throws BusinessException 如果操作失败，可能抛出业务异常。
     */
    public static int createTable(String sql) throws BusinessException {
        // 实例化JDBCAgent，初始化为true表示打开日志。
        JDBCAgent jdbc = new JDBCAgent(true);
        int num = 0;
        try {
            // 执行传入的SQL语句。
            num = jdbc.execute(sql);
        } catch (SQLException e) {
            // SQL执行异常时，打印异常堆栈跟踪。
            e.printStackTrace();
        } finally {
            // 无论执行成功还是失败，都关闭JDBCAgent连接。
            jdbc.close();
        }
        return num;
    }



}
